package com.zxx.injectandroid;

import android.app.Activity;
import android.util.Log;
import android.view.View;

import com.zxx.libinject.adapter.InjectAdapter;
import com.zxx.libinject.adapter.NullAdapter;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import androidx.fragment.app.Fragment;

import static com.zxx.libinject.apt.AbsWriter.SUFFIX;

public final class SimpleDagger {

    static Map<Class<?>, InjectAdapter<?>> sInjectCache = new HashMap<>();

    //Activity
    public static void inject(Activity activity) {
        InjectAdapter<Activity> adapter = getViewAdapter(activity.getClass());
        adapter.injects(activity);
    }

    //Fragment
    public static void inject(Fragment fragment, View rootView) {
        InjectAdapter<Fragment> adapter = getViewAdapter(fragment.getClass());

        if (fuckTheFragment(fragment, rootView)) {
            adapter.injects(fragment);
        }
    }

    public static void inject(View view) {

    }

    //到Fragment 中找到mView字段,然后设置rootView给mView
    private static boolean fuckTheFragment(Fragment fragment, View rootView) {
        try {
            Class<?> v4fragmentClass = fragment.getClass();

            while (v4fragmentClass != Object.class && !v4fragmentClass.equals(Fragment.class)) {
                v4fragmentClass = v4fragmentClass.getSuperclass();
            }

            Field rootViewField = v4fragmentClass.getDeclaredField("mView");

            rootViewField.setAccessible(true);
            rootViewField.set(fragment, rootView);

            Log.e("Tag-->", "### getView " + fragment.getView());
            return true;

        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return false;
    }



    @SuppressWarnings({"unchecked", "rawtypes"})
    private static <T> InjectAdapter<T> getViewAdapter(Class<?> clazz) {
        InjectAdapter<?> adapter = sInjectCache.get(clazz);
        if (adapter == null) {
            String adapterClassName = clazz.getName() + SUFFIX;

            try {
                Class<?> adapterClass = Class.forName(adapterClassName);
                adapter = (InjectAdapter<?>) adapterClass.newInstance();
                sInjectCache.put(adapterClass, adapter);

            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }
        }
        Log.e("Tag->", "### find adapter:" + adapter);
        return adapter == null ? new NullAdapter() : adapter;
    }

}